/*
 * @Author       : Bing Chen chenbing@iocharger.com
 * @Date         : 2024-05-20 22:39:53
 * @LastEditors  : Bing Chen chenbing@iocharger.com
 * @LastEditTime : 2025-03-15 12:40:12
 * @FilePath     : \openchaoji-corelib\evcc\include\OpenChaoJi_evcc_hal.h
 * @Description  : 本文件声明EVCC的HAL适配层接口
 *
 * Copyright (c) 2025 OpenChaoJi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the icense for the specific language governing permissions and
 * limitations under the License.
 *
 */

#ifndef __OPENCHAOJI_EVCC_HAL_H__
#define __OPENCHAOJI_EVCC_HAL_H__

#include "../../shared/include/OpenChaoJi_shared.h"

/******************************* GS对OpenChaoJi提供的hal_handle *******************************/
typedef struct {
   uint8_t evcc_handle;   	 	// 枪号 0:gun0, 1:gun1 ??
} Grasen_hal_handle_t;

/**
 *创建GS handle
*/
OpenChaoJi_hal_handle create_handle(uint8_t gun);

/**
 *销毁GS handle
*/
void destroy_hal_handle(OpenChaoJi_hal_handle handle);

/**
 * 导引电路, IO驱动等
 * 洛阳嘉盛
*/

/**
EVCC 相关接口
*/

/*******************************CAN通信接口*******************************/

/**
 * @brief  CAN接收
 * @param  handle: 句柄
 * @param  can_recv_info: can消息结构体
 * @return 0-接收成功 -1-接受失败
 */
int OpenChaoJi_evcc_hal_information_recv_can_voluation(OpenChaoJi_hal_handle handle, struct can_pdu * can_recv_info);

/**
 * @brief  CAN发送
 * @param  handle: 句柄
 * @param  can_send_info: can消息结构体
 * @return 0-发送成功 -1-发送失败
 */
int OpenChaoJi_evcc_hal_information_send_can_voluation(OpenChaoJi_hal_handle handle, const struct can_pdu * can_send_info);

/******************************控制继电器及反馈******************************/

/**
 * @brief  (A/B类系统)控制直流接触器
 * @param  handle: 句柄
 * @param  ctl: 0-断开 1-闭合
 * @return void
 * @remark C5\C6
 */
void OpenChaoJi_evcc_hal_gbt_close_dc_relay(OpenChaoJi_hal_handle handle,unsigned char ctl);

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B == CONFIG_YES)
/**
 * @brief  (B类系统)控制电子锁锁止
 * @param  handle: 句柄
 * @param  ctl: 0-断开 1-闭合
 * @return void
 */
void OpenChaoJi_evcc_hal_gbt_b_lock(OpenChaoJi_hal_handle handle,unsigned char ctl);

/**
 * @brief  (B类系统)控制S2
 * @param  handle: 句柄
 * @param  ctl: 0-断开 1-闭合
 * @return void
 */
void OpenChaoJi_evcc_hal_gbt_b_close_s2(OpenChaoJi_hal_handle handle,unsigned char ctl);

/**
 * @brief  (B类系统)控制S2p
 * @param  handle: 句柄
 * @param  ctl: 0-断开 1-闭合
 * @return void
 */
void OpenChaoJi_evcc_hal_gbt_b_close_s2p(OpenChaoJi_hal_handle handle,unsigned char ctl);

/**
 * @brief  (B类系统)控制Sv
 * @param  handle: 句柄
 * @param  ctl: 0-断开 1-闭合
 * @return void
 */
void OpenChaoJi_evcc_hal_gbt_b_close_sv(OpenChaoJi_hal_handle handle,unsigned char ctl);
#endif

/**
 * @brief  (A/B类系统)获取直流接触器状态
 * @param  handle: 句柄
 * @return     C5  C6
 *         0   断   断
 *         1   断   通
 *         2   通   断
 *         3   通   通
 * @remark C5\C6
 */
unsigned char OpenChaoJi_evcc_hal_get_status_dc_relay(OpenChaoJi_hal_handle handle);

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B == CONFIG_YES)
/**
 * @brief  (B类系统)获取电子锁锁止
 * @param  handle: 句柄
 * @return 0-断开 1-闭合
 */
bool OpenChaoJi_evcc_hal_gbt_b_is_locked(OpenChaoJi_hal_handle handle);

/**
 * @brief  (B类系统)获取S2状态
 * @param  handle: 句柄
 * @return 0-断开 1-闭合
 */
bool OpenChaoJi_evcc_hal_gbt_b_is_closed_s2(OpenChaoJi_hal_handle handle);

/**
 * @brief  (B类系统)获取S2p状态
 * @param  handle: 句柄
 * @return 0-断开 1-闭合
 */
bool OpenChaoJi_evcc_hal_gbt_b_is_closed_s2p(OpenChaoJi_hal_handle handle);

/**
 * @brief  (B类系统)获取Sv状态
 * @param  handle: 句柄
 * @return 0-断开 1-闭合
 */
bool OpenChaoJi_evcc_hal_gbt_b_is_closed_sv(OpenChaoJi_hal_handle handle);
#endif

/**
 * @brief  (B类系统)获取检测点2电压, A类系统和B类系统对检测点2的定义不同
 * @param  handle: 句柄
 * @return 检测点2电压(单位0.01V)
 * @remark 返回检测点2的检测电压值
 */
int OpenChaoJi_evcc_hal_gbt_get_vol_checkpoint_2(OpenChaoJi_hal_handle handle);

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B == CONFIG_YES)
/**
 * @brief  (B类系统)获取检测点3电压
 * @param  handle: 句柄
 * @return 检测点3电压(单位0.01V)
 * @remark 返回检测点3的检测电压值
 */
int OpenChaoJi_evcc_hal_gbt_b_get_vol_checkpoint_3(OpenChaoJi_hal_handle handle);
#endif

/**
 * @brief  (A/B类系统)获取急停按钮状态
 * @param  handle: 句柄
 * @return 0-断开 1-闭合
 *
 */
bool OpenChaoJi_evcc_hal_is_emergency_pushed(OpenChaoJi_hal_handle handle);

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_A == CONFIG_YES)
/**
 * @brief  (A类系统)获取桩端辅助接口连接状态
 * @param  handle: 句柄
 * @return 0-断开 1-闭合
 */
bool OpenChaoJi_evcc_hal_gbt_a_is_secc_aux_connected(OpenChaoJi_hal_handle handle);
#endif

/****** 此头文件嘉盛和长园共同维护, 为了避免合并冲突, 嘉盛仅修改本行以上部分, 长园只修改本行以下部分 ******/

// 电压电流采集
struct OpenChaoJi_evcc_hal_samp {
    float voltage_in;            //内侧电压（0.1V/位）
    float voltage_out;           //外侧电压（0.1V/位）
    float current;               //电流 （0.1A/位）
};

// 自检参数
struct OpenChaoJi_evcc_hal_selfdata{
    char selfsta_adhesion;       //粘连检测状态
    char selfsta_short;          //短路检测状态
    char selfsta_imd;            //绝缘检测状态

    char selfres_adhesion;       //粘连检测结果
    char selfres_short;          //短路检测结果
    char selfres_imd;            //绝缘检测结果
};
#if 0
/*
 * 功能  启动阶段-自检启动接口
 * 参数  context: 句柄
 * 参数  voltage: 绝缘电压值
 * 返回  0:OK  -1:ERR
 */
int OpenChaoJi_evcc_hal_selfcheck_request_start(OpenChaoJi_hal_handle hal_handle, float voltage);


/*
 * 功能  启动阶段-自检停止接口
 * 参数  context: 句柄
 * 返回  0:OK  -1:ERR
 */
int OpenChaoJi_evcc_hal_selfcheck_request_stop(OpenChaoJi_hal_handle hal_handle);


/*
 * 功能  启动阶段-自检结果获取
 * 参数  context: 句柄
 * 参数  rp_value: 正对地阻值存储地址
 * 参数  rn_value: 负对地阻值存储地址
 * 返回  粘连/短路/绝缘 自检状态和结果
 */
struct OpenChaoJi_evcc_hal_selfdata  OpenChaoJi_evcc_hal_selfcheck_get_result(OpenChaoJi_hal_handle hal_handle);

/*
 * 功能  充电阶段-绝缘启动接口
 * 参数  context: 句柄
 * 参数  voltage: 绝缘电压值
 * 返回  0:OK  -1:ERR
 */
int OpenChaoJi_evcc_hal_imd_request_start(OpenChaoJi_hal_handle hal_handle, float voltage);


/*
 * 功能  充电阶段-绝缘停止接口
 * 参数  context: 句柄
 * 返回  0:OK  -1:ERR
 */
int OpenChaoJi_evcc_hal_imd_request_stop(OpenChaoJi_hal_handle hal_handle);


/*
 * 功能  充电阶段-绝缘结果获取
 * 参数  context: 句柄
 * 参数  rp_value: 正对地阻值存储地址
 * 参数  rn_value: 负对地阻值存储地址
 * 返回  -1: ERR   0:OK  1:Checking
 */
int OpenChaoJi_evcc_hal_imd_get_result(OpenChaoJi_hal_handle hal_handle,
                                       float *rp_value, float *rn_value);


/*
 * 功能  泄放启动
 * 参数  context: 句柄
 * 返回  0:OK  -1:ERR
 */
int OpenChaoJi_evcc_hal_vent_request_start(OpenChaoJi_hal_handle hal_handle);


/*
 * 功能  泄放停止
 * 参数  context: 句柄
 * 返回  0:OK  -1:ERR
 */
int OpenChaoJi_evcc_hal_vent_request_stop(OpenChaoJi_hal_handle hal_handle);


#endif

/**
 * @brief  电压电流采样值获取
 * @param  handle: 句柄
 * @param  samp_value: 采样值存储地址
 * @return 0-成功  -1-失败
 */
int OpenChaoJi_evcc_hal_sampling_value(OpenChaoJi_hal_handle handle,
                                       struct OpenChaoJi_evcc_hal_samp *samp_value);


/**
 * @brief  (A/B类系统)电池投入
 * @param  handle: 句柄
 * @return void
 */
void OpenChaoJi_evcc_hal_battery_prepare(OpenChaoJi_hal_handle handle);

/**
 * @brief  (A/B类系统)判断电池是否投入成功
 * @param  handle: 句柄
 * @return 0-断开 1-闭合
 */
bool OpenChaoJi_evcc_hal_battery_is_ready(OpenChaoJi_hal_handle handle);

/******************************获取车辆/电池信息******************************/

struct OpenChaoJi_evcc_hal_batt_date {
    unsigned int  year;                     /* 电池组生产日期-年, 1年/位, 0年偏移量, 1985-2235年 */
    unsigned char month;                    /* 电池组生产日期-月, 1月/位, 0月偏移量, 1-12月 */
    unsigned char day;                      /* 电池组生产日期-日, 1日/位, 0日偏移量, 1-31日 */
};

struct OpenChaoJi_evcc_hal_batt_cellvolt {
    unsigned int  id;                       /* 单体蓄电池电压检测点编号, 1/位, 0偏移量, 1-256 */
    unsigned char group;                    /* 单体蓄电池电压检测点分组号, 1/位, 0偏移量, 0-15 */
    unsigned int  voltage;                  /* 单体蓄电池电压检测点采样值, 0.01V/位, 0V偏移量, 0-24V */
};

struct OpenChaoJi_evcc_hal_batt_tempera {
    unsigned int  id;                       /* 电池温度检测点编号, 1/位, 0偏移量, 1-128 */
    int tempera;                            /* 电池温度检测点采样值, 1℃/位, 0℃偏移量, -50℃~200℃ */
};

union OpenChaoJi_evcc_hal_batt_state {
    unsigned int  all;
    struct {
        unsigned int  warn_cellvolt   :2;   /* 单体蓄电池电压过高/过低 00:正常, 01:过高, 10:过低*/
        unsigned int  warn_soc        :2;   /* 动力蓄电池荷电状态SOC过高/过低 00:正常, 01:过高, 10:过低*/
        unsigned int  warn_current    :2;   /* 动力蓄电池充电过流 00:正常, 01:过流 */
        unsigned int  warn_tempera    :2;   /* 动力蓄电池温度过高 00:正常, 01:过高 */
        unsigned int  warn_insul      :2;   /* 动力蓄电池绝缘状态 00:正常, 01:不正常 */
        unsigned int  warn_connector  :2;   /* 动力蓄电池组输出连接器连接状态 00:正常, 01:不正常 */
        unsigned int  charge_enable   :2;   /* 充电允许标识 00:禁止；01:允许 */
        unsigned int  res             :2;   /* 预留 */
    } bits;
};

/**
 * @brief  获取车辆端绝缘监测允许总电压
 * @param  handle: 句柄
 * @return 车辆端绝缘监测允许总电压, 0.1V/位, 0V偏移量
 */
unsigned int OpenChaoJi_evcc_hal_get_imd_request_voltage(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取电池类型
 * @param  handle: 句柄
 * @return 电池类型: 01H:铅酸电池, 02H:镍氢电池, 03H:磷酸铁锂电池,
 *                  04H:锰酸锂电池, 05H:钴酸锂电池, 06H:三元材料电池,
 *                  07H:聚合物锂离子电池, 08H:钛酸锂电池, FFH:其他电池
 */
unsigned char OpenChaoJi_evcc_hal_get_batt_type(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取动力蓄电池额定容量
 * @param  handle: 句柄
 * @return 动力蓄电池额定容量, 0.1Ah/位, 0Ah偏移量
 */
unsigned int OpenChaoJi_evcc_hal_get_rated_capacity(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取动力蓄电池额定总电压
 * @param  handle: 句柄
 * @return 动力蓄电池额定总电压, 0.1V/位, 0V偏移量
 */
unsigned int OpenChaoJi_evcc_hal_get_rated_voltage(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取电池生产厂商名称（数组）
 * @param  handle: 句柄
 * @param  batt_factory: 电池生产厂商名称, 4字节, 标准ASCII码, 低字节在前
 * @return void
 */
void OpenChaoJi_evcc_hal_get_batt_factory(OpenChaoJi_hal_handle handle, unsigned char *batt_factory);

/**
 * @brief  获取电池组序号（数组）
 * @param  handle: 句柄
 * @param  batt_sn: 电池组序号, 4字节, 厂商自行定义
 * @return void
 */
void OpenChaoJi_evcc_hal_get_batt_sn(OpenChaoJi_hal_handle handle, unsigned char *batt_sn);

/**
 * @brief  获取电池组生产日期
 * @param  handle: 句柄
 * @return 电池组生产日期
 */
struct OpenChaoJi_evcc_hal_batt_date OpenChaoJi_evcc_hal_get_batt_date(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取电池组充电次数
 * @param  handle: 句柄
 * @return 电池组充电次数, 1次/位, 0次偏移量
 */
unsigned int OpenChaoJi_evcc_hal_get_charge_cycles(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取电池组产权标识
 * @param  handle: 句柄
 * @return 电池组产权标识, 0:租赁, 1:车自有
 */
unsigned char OpenChaoJi_evcc_hal_get_batt_property(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取扩展车辆识别码（数组）
 * @param  handle: 句柄
 * @param  evin: 扩展车辆识别码, 17字节, 扩展ASCII码, 低字节在前
 * @return void
 */
void OpenChaoJi_evcc_hal_get_evin(OpenChaoJi_hal_handle handle, unsigned char *evin);

/**
 * @brief  获取单体蓄电池最高允许充电电压
 * @param  handle: 句柄
 * @return 单体蓄电池最高允许充电电压, 0.01V/位, 0V偏移量, 0-24V
 */
unsigned int OpenChaoJi_evcc_hal_get_allow_cellvolt(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取动力蓄电池最高允许充电总电压
 * @param  handle: 句柄
 * @return 最高允许充电总电压, 0.1V/位, 0V偏移量
 */
unsigned int OpenChaoJi_evcc_hal_get_allow_voltage(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取动力蓄电池最高允许充电电流
 * @param  handle: 句柄
 * @return 最高允许充电电流, 0.1A/位, 0A偏移量, 0-400A
 */
unsigned int OpenChaoJi_evcc_hal_get_allow_current(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取动力蓄电池标称总能量
 * @param  handle: 句柄
 * @return 动力蓄电池标称总能量, 0.1kWh/位, 0kWh偏移量, 0-1000kWh
 */
unsigned int OpenChaoJi_evcc_hal_get_rated_energy(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取单体蓄电池最高允许温度
 * @param  handle: 句柄
 * @return 单体蓄电池最高允许充电温度, 1℃/位, 0℃偏移量, -50℃~200℃
 */
int OpenChaoJi_evcc_hal_get_allow_tempera(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取整车荷电状态(当前电池SOC)
 * @param  handle: 句柄
 * @return 整车荷电状态, 0.1%/位, 0偏移量, 0-100%
 */
unsigned int OpenChaoJi_evcc_hal_get_batt_soc(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取车辆接口当前电压测量值
 * @param  handle: 句柄
 * @return 车辆接口当前电压测量值, 0.1V/位, 0V偏移量
 */
unsigned int OpenChaoJi_evcc_hal_get_measured_voltage(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取车辆接口当前电流测量值
 * @param  handle: 句柄
 * @return 车辆接口当前电流测量值, 0.1A/位, 0A偏移量, 0-400A
 */
unsigned int OpenChaoJi_evcc_hal_get_measured_current(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取估算剩余充电时间
 * @param  handle: 句柄
 * @return 估算剩余充电时间, 1min/位, 0min偏移量
 */
unsigned int OpenChaoJi_evcc_hal_get_expected_time(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取单体蓄电池最高电压检测点信息
 * @param  handle: 句柄
 * @return 单体蓄电池最高电压检测点信息
 */
struct OpenChaoJi_evcc_hal_batt_cellvolt OpenChaoJi_evcc_hal_get_max_cellvolt(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取单体蓄电池最低电压检测点信息
 * @param  handle: 句柄
 * @return 单体蓄电池最低电压检测点信息
 */
struct OpenChaoJi_evcc_hal_batt_cellvolt OpenChaoJi_evcc_hal_get_min_cellvolt(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取电池最高温度检测点信息
 * @param  handle: 句柄
 * @return 电池最高温度检测点信息
 */
struct OpenChaoJi_evcc_hal_batt_tempera OpenChaoJi_evcc_hal_get_max_tempera(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取电池最低温度检测点信息
 * @param  handle: 句柄
 * @return 电池最低温度检测点信息
 */
struct OpenChaoJi_evcc_hal_batt_tempera OpenChaoJi_evcc_hal_get_min_tempera(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取动力蓄电池工作状态
 * @param  handle: 句柄
 * @return 动力蓄电池工作状态
 */
union OpenChaoJi_evcc_hal_batt_state OpenChaoJi_evcc_hal_get_batt_state(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取单体蓄电池电压检测点数量
 * @param  handle: 句柄
 * @return 单体蓄电池电压检测点数量, 1/位, 0偏移量, 1-256
 */
unsigned int OpenChaoJi_evcc_hal_get_cellvolt_num(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取动力蓄电池温度检测点数量
 * @param  handle: 句柄
 * @return 单体蓄电池电压检测点数量, 1/位, 0偏移量, 1-128
 */
unsigned int OpenChaoJi_evcc_hal_get_tempera_num(OpenChaoJi_hal_handle handle);

/**
 * @brief  获取单体蓄电池电压（数组, 按检测点编号顺序依次排列）
 * @param  handle: 句柄
 * @param  group: 单体蓄电池分组号, 1/位, 0偏移量, 0-15
 * @param  cellvolt: 单体蓄电池电压值, 0.01V/位, 0V偏移量, 0-24V
 * @return void
 */
void OpenChaoJi_evcc_hal_get_cellvolt(OpenChaoJi_hal_handle handle, unsigned char *group, unsigned int *cellvolt);

/**
 * @brief  获取动力蓄电池温度（数组, 按检测点编号顺序依次排列）
 * @param  handle: 句柄
 * @param  tempera: 动力蓄电池温度值, 1℃/位, 0℃偏移量, -50℃~200℃
 * @return void
 */
void OpenChaoJi_evcc_hal_get_tempera(OpenChaoJi_hal_handle handle, int *tempera);

/******************************更新车辆/电池信息******************************/

/**
 * @brief  更新车辆当前时间
 * @param  handle: 句柄
 * @param  time: 同步时间
 * @return 0-成功  -1-失败
 */
int OpenChaoJi_evcc_hal_set_time(OpenChaoJi_hal_handle handle, time_t time);

#endif
